/**
 *
 * @param id
 * @param direction
 * @constructor
 */
function Snake(id) {
  this.id = id;
  this.span = 40;
  this.live = true;
  this.direction = ['up'];
  this.coordinates = [];
  this.speed = 5;
  this.tempSpeed = 0;
  this.revive = false;
}

Snake.prototype.setProp = function (obj) {
  if (obj) {
    for (var k in obj) {
      this[k] = obj[k];
    }
  }
  return this;
}

Snake.prototype.changeRevive = function () {
  this.revive = !this.revive;
  return this;
}

Snake.prototype.speedUp = function () {
  this.speed--;
  if (this.speed < 1) {
    this.speed = 1;
  }
  return this;
}

Snake.prototype.setDirection = function (direction) {
  this.direction[1] = direction;
  return this;
}

Snake.prototype.nextStep = function (foods) {
  if (this.live) {
    this.tempSpeed++;
    if (this.tempSpeed < this.speed) {
      return this;
    }
    this.tempSpeed = 0;
    return this._dealDirection()._dealFood(foods);
  }
  return this;
}

Snake.prototype._negativeDirectionMap = {
  "up": "down",
  "down": "up",
  "left": "right",
  "right": "left"
}

Snake.prototype._backwardDirectionMap = {
  "0 1": "down",
  "0 -1": "up",
  "-1 0": "left",
  "1 0": "right"
}

Snake.prototype._dealDirection = function () {
  var direction = this.direction[this.direction.length - 1];
  // deal with negative direction
  if (this.direction[0] === this._negativeDirectionMap[direction]) {
    var lastPos = this.coordinates[this.coordinates.length - 1];
    var lastButOnePos = this.coordinates[this.coordinates.length - 2];
    direction = this._backwardDirectionMap[(lastPos.x - lastButOnePos.x) + ' ' + (lastPos.y - lastButOnePos.y)];
    this.setDirection(direction);
    this.coordinates.reverse();
  }
  this.direction[0] = direction;
  return this['_' + direction]();
}

Snake.prototype._up = function () {
  if (this.coordinates[0].y === 0) {
    this.coordinates.unshift({x: this.coordinates[0].x, y: this.span - 1});
  } else {
    this.coordinates.unshift({x: this.coordinates[0].x, y: this.coordinates[0].y - 1});
  }
  return this;
}

Snake.prototype._down = function () {
  if (this.coordinates[0].y === this.span - 1) {
    this.coordinates.unshift({x: this.coordinates[0].x, y: 0});
  } else {
    this.coordinates.unshift({x: this.coordinates[0].x, y: this.coordinates[0].y + 1});
  }
  return this;
}

Snake.prototype._left = function () {
  if (this.coordinates[0].x === 0) {
    this.coordinates.unshift({x: this.span - 1, y: this.coordinates[0].y});
  } else {
    this.coordinates.unshift({x: this.coordinates[0].x - 1, y: this.coordinates[0].y});
  }
  return this;
}

Snake.prototype._right = function () {
  if (this.coordinates[0].x === this.span - 1) {
    this.coordinates.unshift({x: 0, y: this.coordinates[0].y});
  } else {
    this.coordinates.unshift({x: this.coordinates[0].x + 1, y: this.coordinates[0].y});
  }
  return this;
}

Snake.prototype._dealFood = function (foods) {
  var me = this, fitFood;
  if (this.live) {
    fitFood = foods.filter(function (food) {
      return food.live && me.coordinates[0].x === food.coordinates[0].x && me.coordinates[0].y === food.coordinates[0].y;
    })[0];
    if (fitFood) {
      // eat warm
      fitFood.effect(this).live = false;
    } else {
      this.coordinates.pop();
    }
  }
  return this;
}

module.exports = Snake;